package com.admin.common.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.ObjectMetadata;

/**
 * 阿里OSS
 */
public class OssUtils {

    @Value("${oss.endPoint}")
    private static String END_POINT;
    @Value("${oss.accessKeyId}")
    private static String ACCESS_KEY_ID;
    @Value("${oss.accessKeySecret}")
    private static String ACCESS_KEY_SECRET;
    @Value("${oss.bucketName}")
    private static String BUCKET_NAME;
    @Value("${oss.ossPath}")
    private static String OSS_PATH;
    @Value("${oss.ossPathChild}")
    private static String OSS_PATH_CHILD;
    @Value("${oss.ossUrl}")
    private static String OSS_URL;


    /*private static final String END_POINT = "http://oss-cn-hangzhou-zwynet-d01-a.internet.cloud-inner.zj.gov.cn";
    private static final String ACCESS_KEY_ID = "rS5uSWQaJZwYfxjH";
    private static final String ACCESS_KEY_SECRET = "4aq9cfGK9NaVSWSK4P3HQ9CpuMgEGW";
    private static final String BUCKET_NAME = "qxj-xcyth";
    public static final String OSS_PATH = "qxj-xcyth";
    public static final String OSS_PATH_CHILD = "uploads/";
    public static final String OSS_URL = "http://qxj-xcyth.oss-cn-hangzhou-zwynet-d01-a.internet.cloud-inner.zj.gov.cn";*/


    /**
     * 上传文件
     * 
     * @param file
     * @param name
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    public static void upload(MultipartFile file, String name) throws IOException {
        OSSClient ossClient = null;
        try {
            ossClient = new OSSClient(END_POINT, ACCESS_KEY_ID,ACCESS_KEY_SECRET);
            if (ossClient.doesBucketExist(BUCKET_NAME)) {
            } else {
                ossClient.createBucket(BUCKET_NAME);
            }
            setBucketPublicReadable(ossClient, OSS_PATH);
            uploadFile(ossClient, OSS_PATH, OSS_PATH_CHILD + name, file);
        } catch (IOException e) {
            e.printStackTrace();
            throw new IOException(e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

    }

    /**
     * 上传文件
     * 
     * @param client
     * @param bucketName
     * @param key
     * @param file
     * @throws OSSException
     * @throws ClientException
     * @throws IOException
     */
    private static void uploadFile(OSSClient client, String bucketName, String key, MultipartFile file)
        throws OSSException, ClientException, IOException {
        ObjectMetadata objectMeta = new ObjectMetadata();
        objectMeta.setContentLength(file.getSize());
        // 可以在metadata中标记文件类型
        // objectMeta.setContentType("image/jpeg");
        //设置Content-disposition的内容模板格式，基于base64编码格式
        String downloadFileNameTemplate = "attachment; filename=\"=?UTF8?B?%s?=\"";
        //对真正文件名称进行base64编码
        String base64FileName = new String(Base64.getEncoder().encode(file.getOriginalFilename().getBytes(StandardCharsets.UTF_8)));
        //设置下载文件的名称
        objectMeta.setContentDisposition(String.format(downloadFileNameTemplate, base64FileName));
        //上传文件
        getContentType(file.getOriginalFilename());
        client.putObject(bucketName, key, file.getInputStream(), objectMeta);
    }

    /**
     * 创建Bucket.
     * 
     * @param client
     * @param bucketName
     * @throws OSSException
     * @throws ClientException
     */
    @SuppressWarnings("unused")
	private void ensureBucket(OSSClient client, String bucketName) throws OSSException, ClientException {
        try {
            // 创建bucket
            client.createBucket(bucketName);
        } catch (Exception e) {

        }
    }

    /**
     * 删除一个Bucket和其中的Objects
     * 
     * @param client
     * @param bucketName
     * @throws OSSException
     * @throws ClientException
     */
    public void deleteBucket(OSSClient client, String bucketName) throws OSSException, ClientException {
        ObjectListing ObjectListing = client.listObjects(bucketName);
        List<OSSObjectSummary> listDeletes = ObjectListing.getObjectSummaries();
        for (int i = 0; i < listDeletes.size(); i++) {
            String objectName = listDeletes.get(i).getKey();
            // 如果不为空，先删除bucket下的文件
            client.deleteObject(bucketName, objectName);
        }
        client.deleteBucket(bucketName);
    }

    /**
     * 把Bucket设置为所有人可读
     * 
     * @param client
     * @param bucketName
     * @throws OSSException
     * @throws ClientException
     */
    public static void setBucketPublicReadable(OSSClient client, String bucketName)
        throws OSSException, ClientException {
        // 创建bucket
        client.createBucket(bucketName);
        // 设置bucket的访问权限，public-read-write权限
        client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
    }

    // 上传文件流
    public static void uploadThumbnail(OSSClient client, String bucketName, String key, InputStream inputStream,
        int size) throws OSSException, ClientException, IOException {
        ObjectMetadata objectMeta = new ObjectMetadata();
        objectMeta.setContentLength(size);
        // 可以在metadata中标记文件类型
        objectMeta.setContentType("image/jpeg");
        client.putObject(bucketName, key, inputStream, objectMeta);
    }


    /**
     * 下载文件
     * 
     * @param client
     * @param bucketName
     * @param key
     * @param filename
     * @throws OSSException
     * @throws ClientException
     */
    public static void downloadFile(OSSClient client, String bucketName, String key, String filename)
        throws OSSException, ClientException {
        client.getObject(new GetObjectRequest(bucketName, key), new File(filename));
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     * 
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public static final String getContentType(String fileName) {
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        // ----------------------------------常见图片格式-------------------------------------
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".pdf".equalsIgnoreCase(fileExtension)) {
            return "application/pdf";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
            || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        // ----------------------------------常见视频格式-------------------------------------
        if (".mp4".equalsIgnoreCase(fileExtension)) {
            return "video/mpeg4";
        }
        if (".avi".equalsIgnoreCase(fileExtension)) {
            return "video/x-msvideo";
        }
        if (".flv".equalsIgnoreCase(fileExtension)) {
            return "video/x-flv";
        }
        if (".mpg".equalsIgnoreCase(fileExtension)) {
            return "video/mpg";
        }
        if (".rmvb".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.rn-realmedia-vbr";
        }
        if (".rm".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.rn-realmedia";
        }
        if (".wma".equalsIgnoreCase(fileExtension)) {
            return "audio/x-ms-wma";
        }
        if (".mov".equalsIgnoreCase(fileExtension)) {
            return "video/quicktime";
        }
        if (".wmv".equalsIgnoreCase(fileExtension)) {
            return "video/x-ms-wmv";
        }
        // ----------------------------------其它一些格式-------------------------------------
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || ".pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || ".docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        if (".xlsx".equalsIgnoreCase(fileExtension)) {
            return "text/xlsx";
        }
        if (".xls".equalsIgnoreCase(fileExtension)) {
            return "text/xls";
        }
        return null;
    }
}
